using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text; 
using System.IO;
using System.Xml;
using System.Globalization;

public class lwTools
{
	static public NumberFormatInfo m_NumberFormatInfo;
	static public CultureInfo m_CultureInfo;

	public static string LoadTextFile( string sFileName )
	{
		string sTxt = string.Empty;
		// Test if the file is present in the local directory (for testing)
		string sCompleteFileName = Application.dataPath 
#if !UNITY_ANDROID
			+ "/.." 
#endif
			+ "/"	+ sFileName + ".xml";
		if( File.Exists(sCompleteFileName) )
		{ // ok, load the file
			sTxt = File.ReadAllText( sCompleteFileName );
			Debug.Log( "Text File loaded from : " + sCompleteFileName );
			
			if( !string.IsNullOrEmpty(sTxt) && sTxt[0].GetHashCode()==0xFEFF )
			{
				sTxt = sTxt.Substring( 1 );
			}
		}
		else
		{
			TextAsset TextFile = Resources.Load( sFileName ) as TextAsset;
			if(TextFile == null)
			{
				Debug.LogWarning( "Can't open Resource " + sFileName + " !" );
				return string.Empty;
			}
			else
				sTxt = TextFile.text;
		}
		
		return sTxt;
	}
	
	public static string LoadTextFile( string sFileName, string extension, AssetBundle pAssetBundle )
	{
		string sTxt = string.Empty;
		
		// Test if the file is present in the local directory (for testing)
		string sCompleteFileName = Application.dataPath 
#if !UNITY_ANDROID
			+ "/.." 
#endif
			+ "/"	+ sFileName + extension;
		
		if( File.Exists(sCompleteFileName) )
		{ // ok, load the file
			sTxt = File.ReadAllText( sCompleteFileName );
			Debug.Log( "Text File loaded from : " + sCompleteFileName );
		}
		else
		{ // Load file from resources
			
			TextAsset sTextFile = null;
			if ( pAssetBundle != null )
			{
				int nStart = sFileName.LastIndexOf( "/" );
				if( nStart >= 0 )
					sFileName = sFileName.Substring( nStart+1 );
				sTextFile = pAssetBundle.Load( sFileName, typeof(TextAsset) ) as TextAsset;
			}
			else
				sTextFile = Resources.Load( sFileName ) as TextAsset;
			if ( sTextFile != null )
			{
				sTxt = sTextFile.ToString();
				Debug.Log( "Text File loaded from : " + sFileName );
			}
			else
				Debug.LogWarning( "Can't open Resource " + sFileName + " !" );
		}
		if( !string.IsNullOrEmpty(sTxt) && sTxt[0].GetHashCode()==0xFEFF )
		{
			sTxt = sTxt.Substring( 1 );
		}
		return sTxt;
	}
	
	static byte[] LoadBinaryFile( string sFileName, string extension )
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		string sCompleteFileName = "jar:file://" + Application.dataPath + "!/External/" + sFileName + extension;
		WWW test = new WWW(sCompleteFileName);
		while(!test.isDone);
		return test.bytes;
#else
	#if UNITY_IPHONE && !UNITY_EDITOR
		string sCompleteFileName = Application.dataPath + "/../" + sFileName + extension;
	#else
		string sCompleteFileName = Application.dataPath + "/../External/" + sFileName + extension;
	#endif
		
		if( File.Exists(sCompleteFileName) )
		{ // ok, load the file
			return File.ReadAllBytes( sCompleteFileName );
		}
#endif
		Debug.Log( "Binary File not found : " + sCompleteFileName );
		return null;
}
	
	public static string LoadEncryptedTextFile( string sPath )
	{
		RC4 rc4 = new RC4();
		byte[] bBinary = LoadBinaryFile( sPath, ".enc" );
		if ( bBinary == null )
		{
			Debug.LogWarning("Unable to load " + sPath + ".enc" );
			return string.Empty;
		}
		string sTxt = rc4.EncryptToString( bBinary );
		if( !string.IsNullOrEmpty(sTxt) && sTxt[0].GetHashCode()==0xFEFF )
		{
			sTxt = sTxt.Substring( 1 );
		}
		return sTxt;
	}
	
	static public bool ReadBool( string sValue, bool bDefault)
	{
		if ( sValue != null && sValue != string.Empty )
		{
			switch ( sValue.ToUpper() )
			{
			case "FALSE":
			case "OFF":
			case "NO":
			case "0":
				return false;
			case "TRUE":
			case "ON":
			case "YES":
			case "1":
			case "-1":
				return true;
			}
		}
		return bDefault;
	}
					
	static public float ReadFloatFromXml( ref XmlReader xr )
	{
		if ( xr.Read() )
			return float.Parse(xr.Value);
		return 0;
	}
	
	static public int ReadIntFromXml( ref XmlReader xr )
	{
		if ( xr.Read() )
			return int.Parse(xr.Value);
		return 0;
	}

	static public Vector3 ReadVector3FromXml( ref XmlReader xr )
	{
		Vector3 vResult = Vector3.zero;
		if ( FindStartElement( "X", ref xr ) )
			vResult.x = ReadFloatFromXml( ref xr );
		if ( FindStartElement( "Y", ref xr ) )
			vResult.y = ReadFloatFromXml( ref xr );
		if ( FindStartElement( "Z", ref xr ) )
			vResult.z = ReadFloatFromXml( ref xr );
		return vResult;
	}
	
	static public void WriteVector3ToXml( ref XmlWriter xw, string sName, Vector3 vVect )
	{
		xw.WriteStartElement( sName );
			xw.WriteStartElement( "x" );
				xw.WriteString( XmlConvert.ToString(vVect.x) );
			xw.WriteEndElement();
			xw.WriteStartElement( "y" );
				xw.WriteString( XmlConvert.ToString(vVect.y) );
			xw.WriteEndElement();
			xw.WriteStartElement( "z" );
				xw.WriteString( XmlConvert.ToString(vVect.z) );
			xw.WriteEndElement();
		xw.WriteEndElement();
	}
	
	static public bool FindStartElement( string sName, ref XmlReader xr )
	{
		sName = sName.ToUpper();
		while( xr.Read() && !( xr.NodeType == XmlNodeType.Element && xr.Name.ToUpper() == sName ) );
		if ( xr.NodeType != XmlNodeType.Element || xr.Name.ToUpper() != sName )
        {
			Debug.LogError( "Error in XML File, can't find expected " + sName );
			return false;
		}
		return true;
	}
	
	static public string TimeToString( float fTime )
	{
		fTime = Mathf.Round(fTime);
		int nHours = Mathf.FloorToInt(fTime/3600);
		fTime -= nHours*3600;
		int nMin = Mathf.FloorToInt(fTime/60);
		fTime -= nMin*60;
		int nSec = Mathf.RoundToInt(fTime);
//		int nSec = Mathf.FloorToInt(fTime);
//		fTime -= nSec;
//		int nCent = Mathf.RoundToInt(fTime*100);
		return nHours.ToString("00") + ":" + nMin.ToString("00") + ":" + nSec.ToString("00"); // + "." + nCent.ToString("00");
	}
		
	static public string GetXmlAttribute( XmlReader xr, string sAttribute, string sDefault )
	{
		try
		{
			string sResult = xr.GetAttribute( sAttribute );
			if ( string.IsNullOrEmpty( sResult ) )
				return sDefault;
			else
				return sResult;
		}
		catch
		{
			return sDefault;
		}
	}
	
	static public int GetXmlAttributeInt( XmlReader xr, string sAttribute, int nDefault )
	{
		return int.Parse( GetXmlAttribute( xr, sAttribute, nDefault.ToString() ) );
	}
	static public float GetXmlAttributeFloat( XmlReader xr, string sAttribute, float fDefault )
	{
		return float.Parse( GetXmlAttribute( xr, sAttribute, fDefault.ToString() ) );
	}
	static public bool GetXmlAttributeBool( XmlReader xr, string sAttribute, bool bDefault )
	{
		return ReadBool( GetXmlAttribute( xr, sAttribute, bDefault.ToString() ), bDefault );
	}
	static public Vector2 GetXmlAttributeVector2( XmlReader xr, Vector2 vDefault )
	{
		return new Vector2( GetXmlAttributeFloat( xr, "x", vDefault.x ),		
		                    GetXmlAttributeFloat( xr, "y", vDefault.y ) );
	}
	static public Vector3 GetXmlAttributeVector3( XmlReader xr, Vector3 vDefault )
	{
		return new Vector3( GetXmlAttributeFloat( xr, "x", vDefault.x ),		
		                    GetXmlAttributeFloat( xr, "y", vDefault.y ),
		                    GetXmlAttributeFloat( xr, "z", vDefault.z ) );
	}
	static public Vector3 GetXmlAttributeVectorScale3( XmlReader xr, Vector3 vDefault )
	{
		return new Vector3( GetXmlAttributeFloat( xr, "scalex", vDefault.x ),		
		                    GetXmlAttributeFloat( xr, "scaley", vDefault.y ),
		                    GetXmlAttributeFloat( xr, "scalez", vDefault.z ) );
	}

	static public IEnumerator LoadTextureFromExternal( Sprite pSprite, string sFileName, string sSubPath)
	{
		return LoadTextureFromExternal( pSprite, sFileName, ".jpg", sSubPath, 1024, 768, FilterMode.Bilinear);
	}
	
	static public IEnumerator LoadTextureFromExternal( Sprite pSprite, string sFileName, string sSubPath, FilterMode filter)
	{
		return LoadTextureFromExternal( pSprite, sFileName, ".jpg", sSubPath, 1024, 768, filter);
	}
	
	static public IEnumerator LoadTextureFromExternal( Sprite pSprite, string sFileName, string sExtension, string sSubPath, int nWidth, int nHeight)
	{
		return LoadTextureFromExternal( pSprite, sFileName, sExtension, sSubPath, nWidth, nHeight, FilterMode.Bilinear );
	}
	
	static public IEnumerator LoadTextureFromExternal( Sprite pSprite, string sFileName, string sExtension, string sSubPath, int nWidth, int nHeight, FilterMode filter)
	{
		string sPath = GetTexturePath( sFileName, sExtension, sSubPath );
		Debug.Log( "Loading image at location : " + sPath );
		WWW download = new WWW(sPath);
		Texture2D pTexture = CreateTexture2D( nWidth, nHeight, filter );
		yield return download;
		if ( ApplyTextureFromWww(download, pTexture ) )
		{
			pSprite.GetComponent<MeshRenderer>().material.mainTexture = pTexture;
			pSprite.SetUVs( new Rect( 0, 0, 1, 1) );//0.75f) );
			pSprite.SetColor( Color.white );
			pSprite.SetCamera();
		}
		else
			Debug.LogWarning( "Texture " +  sPath + " not found !" );
	}
	
	static public Texture2D CreateTexture2D( int nWidth, int nHeight, FilterMode filter )
	{
		Texture2D pTexture = null;
		if ( Application.platform == RuntimePlatform.IPhonePlayer )
		{
			pTexture = new Texture2D(nWidth, nHeight, TextureFormat.RGB565, false);
		}
		else if ( Application.platform == RuntimePlatform.Android )
		{
			pTexture = new Texture2D(nWidth, nHeight, TextureFormat.RGB565, false);
		}
		else 
		{
			pTexture = new Texture2D(nWidth, nHeight, TextureFormat.RGB24, false);
		}
//		pTexture.filterMode = (Screen.width < 1024)?FilterMode.Bilinear:FilterMode.Point; 
		pTexture.filterMode = filter;
		return pTexture;
	}
	
	static public string GetTexturePath( string sFileName, string sExtension, string sSubPath )
	{
		string sPath = sFileName;
		if ( Application.platform == RuntimePlatform.IPhonePlayer )
		{
			sPath = "file://" + Application.dataPath + "/../" + sPath + ".jpg"; // only jpg on iOS
		}
		else if ( Application.platform == RuntimePlatform.Android )
		{
			sPath = "jar:file://" + Application.dataPath + "!/External/" + sPath + sExtension;
		}
		else 
		{ // on Standalone players, test file existence for fallback folders
			string sFile = sPath + sExtension;
			sPath = Application.dataPath + "/../External/" + sFile;
			if ( !System.IO.File.Exists( sPath ) )
			{
				if ( (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor) )
					sPath = Application.dataPath + "/../../Data/Pictures/" + sSubPath + sFile;
				else
					sPath =  Application.dataPath + "/../../../Data/Pictures/" + sSubPath + sFile;
			}
			sPath = "file://" + sPath;
		}
		return sPath;
	}
	
	static public bool ApplyTextureFromWww( WWW download, Texture2D pTexture )
	{
		if ( download	!= null && string.IsNullOrEmpty( download.error ) )
		{
			download.LoadImageIntoTexture( pTexture );
			download.Dispose();
			download = null;
			Resources.UnloadUnusedAssets();
			System.GC.Collect();
			return true;
		}
		return false;
	}
	
	static public IEnumerator LoadImageInTextureFromExternal( Texture2D pTexture, string sFileName, string sExtension, string sSubPath )
	{
		string sPath = GetTexturePath( sFileName, sExtension, sSubPath );
		Debug.Log( "Loading image at location : " + sPath );
		WWW download = new WWW(sPath);
		yield return download;
		if ( !ApplyTextureFromWww(download, pTexture ) )
			Debug.LogWarning( "Texture " +  sPath + " not found !" );
	}
	static public IEnumerator LoadImageInTextureFromExternal( Texture2D pTexture, string sPath )
	{
		Debug.Log( "Loading image at location : " + sPath );
		WWW download = new WWW(sPath);
		yield return download;
		if ( !ApplyTextureFromWww(download, pTexture ) )
			Debug.LogWarning( "Texture " +  sPath + " not found !" );
	}
	
	// ****************************************************
	// ****************************************************
	// Scroll and zoom
	// ****************************************************
	// ****************************************************
	//iphone input
	static private int m_nTouchId1 = -1;
	static private int m_nTouchId2 = -1;
	static private Vector2 m_vTouchPoint1;
	static private Vector2 m_vTouchPoint2;
	static private Vector2 m_vLastTouchPoint1;
	static private Vector2 m_vLastTouchPoint2;
	static private float m_fPinchInitialDistance = 0;
	
	static public void InitScrollAndZoom()
	{
		m_nTouchId1 = -1;
		m_nTouchId2 = -1;
		m_fPinchInitialDistance = 0;
	}
	
	public static void ManageScrollAndZoom( ref float fZoom, ref Vector2 vScroll )
	{
		float oldZoom = fZoom;

		if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android )
		{	
			m_vLastTouchPoint1 = m_vTouchPoint1;
			m_vLastTouchPoint2 = m_vTouchPoint2;
			bool bMove = false;
			if ( m_nTouchId1 != -1 )
			{ // on teste l'état des doigts appuyés
				bool bTouch1 = false;
				bool bTouch2 = false;
				for( int i=0; i<Input.touchCount; i++ )
				{
					Touch touch = Input.GetTouch(i);
					Vector3 vPos = UIManager.RemapInputPosition( touch.position );
					
					if ( touch.fingerId == m_nTouchId1 )
					{
						bTouch1 = true;
						if ( touch.phase == TouchPhase.Moved )
						{
							m_vTouchPoint1 = vPos;
							bMove = true;
						}
					}
					else if (touch.fingerId == m_nTouchId2)
					{
						bTouch2 = true;
						if ( touch.phase == TouchPhase.Moved )
						{
							m_vTouchPoint2 = vPos;
							bMove = true;
						}
					}
					
				}
				
				if ( !bTouch1 && !bTouch2 )
				{
					InitScrollAndZoom(); // plus de doigt
				}
				else
				{
					if ( bTouch2 )
					{ 
						if ( !bTouch1 )
						{ // first finger ended -> swap
//							Debug.Log( "Finger 1 released -> Swapping fingers." );
							m_nTouchId1 = m_nTouchId2;
							m_nTouchId2 = -1;
							m_vLastTouchPoint1 = m_vLastTouchPoint2;
							m_vTouchPoint1 = m_vTouchPoint2;
							m_fPinchInitialDistance = 0;
						}
					}
					else
					{
						m_nTouchId2 = -1;
						if ( !bTouch1 )
							m_nTouchId1 = -1;
						m_fPinchInitialDistance = 0;
					}
				}
			}
			
			if ( m_nTouchId2 == -1 )
			{ // on cherche un nouveau doigt
				for( int i=0; i<Input.touchCount; i++ )
				{
					Touch touch = Input.GetTouch(i);
					Vector3 vPos = UIManager.RemapInputPosition( touch.position );
					
					if ( m_nTouchId1 == -1  )
					{
//						Debug.Log( "New Finger 1 at " + vPos );
						m_nTouchId1 = touch.fingerId;
						m_vLastTouchPoint1 = m_vTouchPoint1 = vPos;
					}
					else if ( m_nTouchId1 != touch.fingerId )
					{
//						Debug.Log( "New Finger 2 at " + vPos );
						m_nTouchId2 = touch.fingerId;
						m_vLastTouchPoint2 = m_vTouchPoint2 = vPos;
						break; // les autres doigts ne nous intéressent pas
					}
				}
			}
			
			if ( m_nTouchId1 != -1 && bMove )
			{ // at least one finger has moved
				if ( m_nTouchId2 == -1 )
				{ // scroll
//					Debug.Log( "Scrolling..." );
					vScroll += (m_vTouchPoint1 - m_vLastTouchPoint1);
				}
				else
				{ // zoom
					float pinchDistance = Vector2.Distance(m_vTouchPoint1, m_vTouchPoint2);
//					Debug.Log( "Pinch distance : " + pinchDistance );
					if ( m_fPinchInitialDistance != 0 )
						fZoom *= pinchDistance / m_fPinchInitialDistance;
					m_fPinchInitialDistance = pinchDistance;
				}
			}
			
		}
		else 
		{ // PC Version
			
			if ( Input.GetMouseButton( 2 ) )
			{ // scroll
				float fTranslationSpeed = 10;
				vScroll.x += fTranslationSpeed*Input.GetAxis("Mouse X");	
				vScroll.y += fTranslationSpeed*Input.GetAxis("Mouse Y");	
			} 
			else 
			{ // zoom
				float fMouseWheel = Input.GetAxis ("Mouse ScrollWheel"); 
				if (fMouseWheel != 0)
				{
					fZoom *= (1 + fMouseWheel); //(fMouseWheel/10.0f));	
//					Debug.Log( "Zoom Mouse Wheel = " + fMouseWheel + " Zoom : " + oldZoom + " -> " + fZoom );
				}
			}
		}
		if ( oldZoom != fZoom )
		{
			float fMaxZoom = ((Screen.width <= 480) ? 3.5f : 1.5f); //(float)SuperCamera.ScreenSize.width / 1024.0f * ((Screen.width <= 480) ? 3.5f : 1.5f);		
			fZoom = Mathf.Clamp( fZoom, 0.5f, fMaxZoom );
			if ( oldZoom != 0 )
			{
				float fRatio = fZoom / oldZoom;
				vScroll *= fRatio;
			}
		}
	}
		
	static public string GetAssetBundlePath( string sName, string sGameName )
	{
		string sPrefix  = string.IsNullOrEmpty(sGameName)?"":(sGameName+"_");
		string sSubPath = string.IsNullOrEmpty(sGameName)?"":(sGameName+"/");
		
		if ( Application.platform == RuntimePlatform.IPhonePlayer )
			return "file://" + Application.dataPath + "/../" + sPrefix + sName + ".assetbundle";
		else if ( Application.platform == RuntimePlatform.Android )
			return "jar:file://" + Application.dataPath + "!/External/" + sPrefix + sName + ".assetbundle";
		else if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor) {
#if UNITY_IPHONE
				return "file://" + Application.dataPath + "/../../Build/iOSFinal/AssetBundles/" + sSubPath + sPrefix + sName + ".assetbundle";		
#else
				return "file://" + Application.dataPath + "/../../Build/PC/AssetBundles/" + sSubPath + sPrefix + sName + ".assetbundle";
#endif
				
		}
		else if( Application.platform == RuntimePlatform.WindowsPlayer) 
		{
			string sPath = Application.dataPath + "/../External/" + sPrefix + sName + ".assetbundle";
			if(System.IO.File.Exists(sPath))
				return "file://" + sPath;
			else
				return "file://" + Application.dataPath + "/../AssetBundles/" + sSubPath + sPrefix + sName + ".assetbundle";
		}
		else
			return "file://" + Application.dataPath + "/../External/" + sPrefix + sName + ".assetbundle";
		
	}
	
	static public void ToStringSeparator( ref string sToModify, int valueToString )
	{
		ToStringSeparator( ref sToModify, valueToString, false, string.Empty, false, string.Empty, 0 );
	}	
	static public void ToStringSeparator( ref string sToModify, int valueToString, bool bHasGroupSep, string sGroupSeparator )
	{
		ToStringSeparator( ref sToModify, valueToString, bHasGroupSep, sGroupSeparator, false, string.Empty, 0 );
	}	
	static public void ToStringSeparator( ref string sToModify, int valueToString, bool bHasDigit, string sDigitSeparator, int nDigitNumber )
	{
		ToStringSeparator( ref sToModify, valueToString, false, string.Empty, bHasDigit, sDigitSeparator, nDigitNumber );
	}
	static public void ToStringSeparator( ref string sToModify, int valueToString, bool bHasGroupSep, string sGroupSeparator, bool bHasDigit, string sDigitSeparator, int nDigitNumber )
	{
		lwLangManager langManager = lwLangManager.GetInstance();
		string nameLang = langManager.GetCurrentLanguageName().ToLower();
		
		m_CultureInfo = CultureInfo.InvariantCulture;
		m_NumberFormatInfo = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
		
		m_NumberFormatInfo.NumberGroupSeparator = CultureInfo.CurrentCulture.NumberFormat.CurrencyGroupSeparator;
		m_NumberFormatInfo.NumberDecimalDigits = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits;
		m_NumberFormatInfo.NumberDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
		
		if( bHasDigit )
		{
			m_NumberFormatInfo.NumberDecimalSeparator = sDigitSeparator;
			m_NumberFormatInfo.NumberDecimalDigits = nDigitNumber;
		}		
		if( bHasGroupSep )
		{
			m_NumberFormatInfo.NumberGroupSeparator = sGroupSeparator;
		}
		else
		{
			switch( nameLang )
			{
			case "en":
				m_CultureInfo = new CultureInfo( "en-US", false );
				break;
			case "fr":
				m_CultureInfo = new CultureInfo( "fr-FR", false );
				break;
			case "ge":
				m_CultureInfo = new CultureInfo( "de-DE", false );
				break;
			case "sp":
				m_CultureInfo = new CultureInfo( "es-ES", false );
				break;
			case "it":
				m_CultureInfo = new CultureInfo( "it-IT", false );
				break;
			}
			m_NumberFormatInfo.NumberGroupSeparator = m_CultureInfo.NumberFormat.CurrencyGroupSeparator;
		}
		
		sToModify = valueToString.ToString( "N", m_NumberFormatInfo );
	}
	
	static public void TestSurveyOnQuit()
	{
#if !UNITY_IPHONE && !UNITY_ANDROID
		if ( lwBuildSettings.IsSurveyBuild() )
		{
			string sFileName = Application.dataPath + "/../External/BFGSurvey.txt";
			Debug.Log( "SURVEY : opening " + sFileName );
			if( File.Exists(sFileName) )
			{ // ok, load the file
				string sUrl = File.ReadAllText( sFileName );
				if ( !string.IsNullOrEmpty(sUrl) )
				{
					Application.OpenURL( sUrl );
					Debug.Log( "SURVEY : URL : " + sUrl );
				}
			}
		}
#endif
	}	
	
	static public IEnumerable<string> GetFiles( string path )
	{
	    Queue<string> queue = new Queue<string>();
	    queue.Enqueue(path);
	    while (queue.Count > 0)
		{
	        path = queue.Dequeue();
	        try {
	            foreach ( string subDir in Directory.GetDirectories( path ) )
	                queue.Enqueue(subDir);
	        }
	        catch(Exception ex) {
	            Console.Error.WriteLine(ex);
	        }
	        string[] files = null;
	        try {
	            files = Directory.GetFiles(path);
	        }
	        catch (Exception ex) {
	            Console.Error.WriteLine(ex);
	        }
	        if (files != null)
	            for(int i = 0 ; i < files.Length ; i++)
	                yield return files[i];
    	}
	}
} 